Test Setup Failed
Push — master ( 8ee19e...25278d )
by recca
05:07 queued 46s
created

terminal.js ➔ ???   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 56

Duplication

Lines 0
Ratio 0 %

Importance

Changes 13
Bugs 0 Features 0
Metric Value
cc 2
nc 2
nop 2
dl 0
loc 56
rs 9.7251
c 13
b 0
f 0

1 Function

Rating   Name   Duplication   Size   Complexity  
A terminal.js ➔ ... ➔ ??? 0 14 1

How to fix   Long Method   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
'use strict';
2
3
import './jquery';
4
import 'jquery-mousewheel';
5
import 'jquery.terminal';
6
import 'jquery.terminal/js/unix_formatting';
7
8
import './polyfill';
9
import OutputFormatter from './output-formatter';
10
import Loading from './loading';
11
12
import Artisan from './commands/artisan';
13
import Composer from './commands/composer';
14
import Default from './commands/default';
15
import Help from './commands/help';
16
import Mysql from './commands/mysql';
17
import Tinker from './commands/tinker';
18
import Vi from './commands/vi';
19
20
class Terminal {
21
    constructor(element, options = {}) {
22
        this.$element = $(element);
23
        this.$parent = this.$element.parent();
24
        this.$win = $(window);
25
        this.$term = null;
26
        let parentTagName = this.$parent.prop('tagName').toLowerCase();
27
28
        if (!options.endPoint) {
29
            options.endPoint = options.endpoint;
30
        }
31
32
        Object.assign(this, {
33
            options: Object.assign({}, options),
34
            formatter: new OutputFormatter,
35
            prompt: "$ ",
36
        });
37
38
        this.$element.terminal(this.run.bind(this), {
39
            greetings: this.greetings(),
40
            onInit: (term) => {
41
                this.$term = term;
42
                this.loading = new Loading(term);
43
                this.commands = [
44
                    new Help(this, options),
45
                    new Artisan(this, options),
46
                    new Composer(this, options),
47
                    new Mysql(this, options),
48
                    new Tinker(this, options),
49
                    new Vi(this, options),
50
                    new Default(this, options),
51
                ];
52
                this.run('list');
53
            },
54
            onClear: () => {
55
                this.serverInfo();
56
            },
57
            prompt: this.prompt
58
        });
59
60
        this.$win.on('resize', () => {
61
            if (parentTagName === 'body') {
62
                let width = this.$parent.width() - 20;
63
                let height = this.$parent.height() - 20;
64
                this.$element.width(width);
65
                this.$element.height(height);
66
            } else {
67
                this.scrollToBottom();
68
            }
69
        }).trigger('resize');
70
71
        this.$parent.on('click', () => {
72
            if (this.$term) {
73
                this.$term.focus();
74
            }
75
        });
76
    }
77
78
    scrollToBottom(delay = 200) {
79
        setTimeout(() => {
80
            this.$element.parent().animate({
81
                scrollTop: 9e9
82
            });
83
        }, delay);
84
    }
85
86
    run(command) {
87
        for (let interpreter in this.options.interpreters) {
88
            if (command === interpreter) {
89
                let prompt = this.options.interpreters[interpreter];
90
                this.interpreter(prompt);
91
                return;
92
            }
93
        }
94
95
        let cmd = $.terminal.parseCommand(command.trim());
96
        for (let i = 0; i < this.commands.length; i++) {
97
            let command = this.commands[i];
98
            if (command.match(cmd.name) === true) {
99
                command.call(cmd);
100
                break;
101
            }
102
        }
103
    }
104
105
    interpreter(prompt) {
106
        this.$term.push((command) => {
107
            this.run(`${prompt.replace(/\s+/g, '-')} ${command}`);
108
        }, {
109
            prompt: `${prompt}> `
110
        })
111
    }
112
113
    greetings() {
114
        return [
115
            " __                        _    _____              _         _ ",
116
            "|  |   ___ ___ ___ _ _ ___| |  |_   ____ ___ _____|_|___ ___| |",
117
            "|  |__| .'|  _| .'| | | -_| |    | || -_|  _|     | |   | .'| |",
118
            "|_____|__,|_| |__,|\\_/|___|_|    |_||___|_| |_|_|_|_|_|_|__,|_|",
119
            "",
120
            "Copyright (c) 2015 Recca Tsai <http://phpwrite.blogspot.tw/>",
121
            "",
122
            "Type a command, or type `" + this.info('help') + "`, for a list of commands.",
123
            "",
124
        ].join("\n");
125
    }
126
127
    serverInfo() {
128
        if (this.$term.level() > 1) {
129
            return;
130
        }
131
132
        let host = `${this.info(this.options.username)}${this.info('@')}${this.info(this.options.hostname)}`;
133
        let os = this.question(`${this.options.os}`);
134
        let path = this.comment(`${this.options.basePath}`);
135
        this.$term.echo(`${host} ${os} ${path}`);
136
        this.scrollToBottom();
137
    }
138
139
    error(text) {
140
        return this.formatter.error(text);
141
    }
142
143
    info(text) {
144
        return this.formatter.info(text);
145
    }
146
147
    comment(text) {
148
        return this.formatter.comment(text);
149
    }
150
151
    question(text) {
152
        return this.formatter.question(text);
153
    }
154
155
    echo(text) {
156
        let regex = new RegExp("(\\033\\[(\\d+)(;\\d+)?m(((?!\\033\\[\\d+).)*)\\033\\[(\\d+)(;\\d+)?m)|(\\[|\\])", "g");
157
        let content;
158
        text = text.replace(regex, (...m) => {
159
            if (["[", "]"].includes(m[0]) === true) {
160
                return $.terminal.escape_brackets(m[0]);
161
            } else {
162
                content = $.terminal.escape_brackets(m[4]);
163
                switch (m[2]) {
164
                    case '32':
165
                        return this.info(content);
166
                        break;
0 ignored issues
show
Unused Code introduced by
This break statement is unnecessary and may be removed.
Loading history...
167
                    case '33':
168
                        return this.comment(content);
169
                        break;
0 ignored issues
show
Unused Code introduced by
This break statement is unnecessary and may be removed.
Loading history...
170
                    case '37':
171
                        return this.error(content);
172
                        break;
0 ignored issues
show
Unused Code introduced by
This break statement is unnecessary and may be removed.
Loading history...
173
                    default:
174
                        return m[0];
175
                        break;
0 ignored issues
show
Unused Code introduced by
This break statement is unnecessary and may be removed.
Loading history...
176
                }
177
            }
178
        });
179
        text.split("\n").forEach((line) => {
180
            if (line === '') {
181
                line = ' ';
182
            }
183
            this.$term.echo(line);
184
        })
185
    }
186
187
    confirm(message, title = '') {
188
        return new Promise((resolve, reject) => {
189
            let history = this.$term.history();
190
            history.disable();
191
192
            if (title != '') {
193
                this.$term.echo(title);
194
            }
195
            this.$term.echo(message);
196
            this.scrollToBottom();
197
            this.$term.push((result) => {
198
                if (this.toBoolean(result) === true) {
199
                    resolve(true);
200
                } else {
201
                    reject(false)
202
                    this.serverInfo();
203
                }
204
                this.$term.pop();
205
                history.enable();
206
                return;
0 ignored issues
show
Unused Code introduced by
This return has no effect and can be removed.
Loading history...
207
            }, {
208
                prompt: ' > '
209
            });
210
        });
211
    }
212
213
    toBoolean(value) {
214
        switch (value) {
0 ignored issues
show
Coding Style introduced by
As per coding-style, switch statements should have a default case.
Loading history...
215
            case 'y':
216
            case 'yes':
217
            case 'true':
218
                return true;
219
                break;
0 ignored issues
show
Unused Code introduced by
This break statement is unnecessary and may be removed.
Loading history...
220
            case 'n':
221
            case 'no':
222
            case 'false':
223
            case '':
224
                return false;
225
                break;
0 ignored issues
show
Unused Code introduced by
This break statement is unnecessary and may be removed.
Loading history...
226
        }
227
228
        return false;
229
    }
230
};
231
232
window.Terminal = Terminal;
233